package org.infodavid.common.services.helpers;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import org.infodavid.common.dto.IUserGroupListItem.EUserRole;
import org.infodavid.common.model.IUser;
import org.infodavid.common.model.IUserConnection;
import org.infodavid.common.notifier.INotifierCommand;
import org.infodavid.common.notifier.exceptions.NotifierException;
import org.infodavid.common.reflect.InstantiationHelper;
import org.infodavid.common.services.AbstractService;
import org.infodavid.common.services.IApplicationContext;
import org.infodavid.common.services.exceptions.ServiceException;
import org.infodavid.common.util.IVisitor;

/**
 * The Class NotificationHelper.
 */
public abstract class NotificationHelper extends AbstractService<ServiceException> {
	/** The Constant log. */
	static final Log LOGGER = LogFactory.getLog(NotificationHelper.class);

	/** The INSTANCE. */
	private static final NotificationHelper INSTANCE;

	static {
		try {
			INSTANCE = InstantiationHelper.getInstance().newInstance(NotificationHelper.class);
		}
		catch (final Exception e) {
			LOGGER.fatal("Can not instantiate the " + NotificationHelper.class.getName(), e);

			throw new Error(e);
		}
	}

	/**
	 * Gets the instance.
	 * @return the instance
	 */
	public static NotificationHelper getInstance() {
		return INSTANCE;
	}

	/** The Constant CONTEXT_VAR. */
	protected static final String CONTEXT_VAR = "context";

	/** The Constant ORGANIZATION. */
	protected static final String ORGANIZATION_VAR = "org";

	/** The Constant USER_VAR. */
	protected static final String USER_VAR = "user";

	/** The Constant INITIATOR_VAR. */
	protected static final String INITIATOR_VAR = "initiator";

	/** The Constant RECIPIENT_VAR. */
	protected static final String RECIPIENT_VAR = "recipient";

	/**
	 * The Constructor.
	 */
	protected NotificationHelper() {
		super();
	}

	/**
	 * New command instance.
	 * @param <T> the generic type
	 * @param type the type of command
	 * @return the command
	 * @throws ServiceException the service exception
	 */
	public abstract <T extends INotifierCommand> T newCommandInstance(Class<T> type)
	    throws ServiceException;

	/**
	 * Notify users.
	 * @param context the context
	 * @param role the role
	 * @param visitor the visitor
	 * @throws ServiceException the service exception
	 */
	public abstract void notifyUsers(IApplicationContext context, EUserRole role,
	    IVisitor<IUser,Object> visitor) throws ServiceException;

	/**
	 * Notify user password change.
	 * @param context the context
	 * @param user the user
	 * @throws ServiceException the service exception
	 * @throws NotifierException the notifier exception
	 */
	public abstract void notifyUserPasswordChange(IApplicationContext context, IUser user)
	    throws ServiceException, NotifierException;

	/**
	 * Notify user password reset.
	 * @param context the context
	 * @param user the user
	 * @throws ServiceException the service exception
	 * @throws NotifierException the notifier exception
	 */
	public abstract void notifyUserPasswordReset(IApplicationContext context, IUser user)
	    throws ServiceException, NotifierException;

	/**
	 * Notify user registration.
	 * @param context the context
	 * @param user the user
	 * @throws ServiceException the service exception
	 * @throws NotifierException the notifier exception
	 */
	public abstract void notifyUserRegistration(IApplicationContext context, IUser user)
	    throws ServiceException, NotifierException;

	/**
	 * Notify user connection changes.
	 * @param context the context
	 * @param item the item
	 * @throws ServiceException the service exception
	 * @throws NotifierException the notifier exception
	 */
	public abstract void notifyUserConnectionChanges(IApplicationContext context, IUserConnection item)
	    throws ServiceException, NotifierException;

	/**
	 * Notify user connection submitted.
	 * @param context the context
	 * @param connection the connection
	 * @throws ServiceException the service exception
	 * @throws NotifierException the notifier exception
	 */
	public abstract void notifyUserConnectionSubmitted(IApplicationContext context,
	    IUserConnection connection) throws ServiceException, NotifierException;
}
